﻿'use strict';
/**
 * Created by FreezeSoul on 2015/10/23. 
 */
define([
    "app/core/base",
    "app/core/util",
    "../echartsMeta",
    "jquery",
    "underscore",
    'JSONParse',
    'loglevel',
    "echarts"
], function (Chart, Util, Meta, $, _, JSON, log, ec) {

    var property = {
        name: 'eBarProperty',
        config: "property",
        option: []
            .concat($.extend(true, [], Meta.titleProperties))
            .concat($.extend(true, [], Meta.legendProperties))
            .concat($.extend(true, [], Meta.tooltipProperties))
            .concat($.extend(true, [], Meta.toolboxProperties))
            //.concat($.extend(true, [],  _.filter(Meta.tooltipProperties, function(prop){ return ["需要去掉属性的ID-字符串数组"].indexOf(prop.id) === -1 })))
            .concat([
                {
                    group: '其他',
                    id: 'b757a938-727f-4026-9d96-22c86e4ccb18',
                    name: '背景色',
                    enable: false,
                    type: 'color',
                    value: 'transparent',
                    default: 'transparent',
                    link: 'backgroundColor',
                    tooltip: '背景色，如需透明请填写:transparent'
                },
                {
                    group: '其他',
                    id: '9b9ed398-612a-454e-82a4-38ea5478c973',
                    name: '序列颜色',
                    enable: false,
                    type: 'colors',
                    value: [],
                    default: [],
                    data: [
                        '#FE8463', '#9BCA63', '#FAD860', '#60C0DD', '#0084C6',
                        '#D7504B', '#C6E579', '#26C0C0', '#F0805A', '#F4E001',
                        '#B5C334'
                    ],
                    link: 'color',
                    tooltip: '序列颜色会根据给出的颜色集合依次渲染'
                },
                {
                    group: '其他',
                    id: '252c8502-3aae-41d8-8cd1-712818495059',
                    name: 'X轴类型',
                    enable: false,
                    type: 'select',
                    value: 'category',
                    default: 'category',
                    data: [{
                        value: 'category',
                        text: '类目轴'
                    }, {
                        value: 'value',
                        text: '数值轴'
                    }, {
                        value: 'time',
                        text: '时间轴'
                    }],
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.xAxis)) {
                            _.each(option.xAxis, function (xAxis) {
                                Util.setOption("type", _this.value, xAxis);
                            });
                        } else {
                            Util.setOption("type", _this.value, option.xAxis);
                        }
                    },
                    tooltip: 'X坐标轴类型: <br/> 数值轴，适用于连续数据。<br/>类目轴，适用于离散的类目数据，为该类型时必须通过 data 设置类目数据。<br/>时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，星期，日还是小时范围的刻度。'
                },
                {
                    group: '其他',
                    id: '0b774e0b-28c4-4e71-a022-938c68ef9c63',
                    name: 'Y轴类型',
                    enable: false,
                    type: 'select',
                    value: 'value',
                    default: 'value',
                    data: [{
                        value: 'category',
                        text: '类目轴'
                    }, {
                        value: 'value',
                        text: '数值轴'
                    }, {
                        value: 'time',
                        text: '时间轴'
                    }],
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.yAxis)) {
                            _.each(option.yAxis, function (yAxis) {
                                Util.setOption("type", _this.value, yAxis);
                            });
                        } else {
                            Util.setOption("type", _this.value, option.yAxis);
                        }
                    },
                    tooltip: 'Y坐标轴类型: <br/> 数值轴，适用于连续数据。<br/>类目轴，适用于离散的类目数据，为该类型时必须通过 data 设置类目数据。<br/>时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，星期，日还是小时范围的刻度。'
                },
                {
                    group: '其他',
                    id: 'fa99c7f5-1e78-4143-9e5f-b3bd3827cca0',
                    name: 'X轴颜色',
                    enable: false,
                    type: 'color',
                    value: '#333333',
                    default: '#333333',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.xAxis)) {
                            _.each(option.xAxis, function (xAxis) {
                                Util.setOption("axisLine.lineStyle.color", _this.value, xAxis);
                                Util.setOption("axisTick.lineStyle.color", _this.value, xAxis);
                                Util.setOption("axisLabel.textStyle.color", _this.value, xAxis);
                            });
                        } else {
                            Util.setOption("axisLine.lineStyle.color", _this.value, option.xAxis);
                            Util.setOption("axisTick.lineStyle.color", _this.value, option.xAxis);
                            Util.setOption("axisLabel.textStyle.color", _this.value, option.xAxis);
                        }
                    },
                    tooltip: 'X坐标轴轴线、刻度、字体的颜色'
                },
                {
                    group: '其他',
                    id: '1dfdf36a-c120-4b1c-b6ed-d6009eeaa1d0',
                    name: 'Y轴颜色',
                    enable: false,
                    type: 'color',
                    value: '#333333',
                    default: '#333333',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.yAxis)) {
                            _.each(option.yAxis, function (yAxis) {
                                Util.setOption("axisLine.lineStyle.color", _this.value, yAxis);
                                Util.setOption("axisTick.lineStyle.color", _this.value, yAxis);
                                Util.setOption("axisLabel.textStyle.color", _this.value, yAxis);
                            });
                        } else {
                            Util.setOption("axisLine.lineStyle.color", _this.value, option.yAxis);
                            Util.setOption("axisTick.lineStyle.color", _this.value, option.yAxis);
                            Util.setOption("axisLabel.textStyle.color", _this.value, option.yAxis);
                        }
                    },
                    tooltip: 'Y坐标轴轴线、刻度、字体的颜色'
                },
                {
                    group: '其他',
                    id: 'cb259bb6-dfb2-46a1-8b1e-b6893d631c57',
                    name: 'X轴分割线',
                    enable: false,
                    type: 'checked',
                    value: true,
                    default: true,
                    tooltip: '是否显示X轴分割线',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.xAxis)) {
                            _.each(option.xAxis, function (xAxis) {
                                Util.setOption("splitLine.show", _this.value, xAxis);
                            });
                        } else {
                            Util.setOption("splitLine.show", _this.value, xAxis);
                        }
                    }
                },
                {
                    group: '其他',
                    id: 'c879c3a7-c1ad-4058-8745-055aad9d137c',
                    name: 'Y轴分割线',
                    enable: false,
                    type: 'checked',
                    value: true,
                    default: true,
                    tooltip: '是否显示Y轴分割线',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.yAxis)) {
                            _.each(option.yAxis, function (yAxis) {
                                Util.setOption("splitLine.show", _this.value, yAxis);
                            });
                        } else {
                            Util.setOption("splitLine.show", _this.value, yAxis);
                        }
                    }
                }
            ])
            .concat([
                {
                    group: '序列',
                    id: 'f53a0a43-6d1b-43e0-b514-122a8b155ece',
                    name: '序列',
                    type: 'group',
                    items: [],
                    option: [
                        {
                            id: '8d613598-8e08-49ce-908e-7524c305910f',
                            name: '序列名称',
                            enable: true,
                            type: 'text',
                            value: '',
                            default: '',
                            link: 'name',
                            tooltip: '序列名称，用于legend'
                        },
                        {
                            id: '17994381-e1fe-4551-a852-a5a0571ed899',
                            name: '序列绑定',
                            enable: true,
                            type: 'seriesBinding',
                            dataset: '',
                            dimension: '',
                            measure: '',
                            tooltip: '序列绑定设置，与数据集关系'
                        },
                        {
                            id: '3ea78272-30df-47a7-96f8-84453b1959c3',
                            name: '序列类型',
                            enable: true,
                            type: 'select',
                            value: 'bar',
                            default: 'bar',
                            data: [
                                {
                                    value: 'bar',
                                    text: 'Bar'
                                },
                                {
                                    value: 'line',
                                    text: 'Line'
                                },
                                {
                                    value: 'scatter',
                                    text: 'Scatter'
                                }
                            ],
                            link: 'type',
                            tooltip: '序列类型,Bar、Line、Scatter三种类型'
                        },
                        {
                            id: 'a320684c-8ca5-49f0-aab7-853e0fde9e5c',
                            name: '过滤列名称',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            tooltip: '绑定数据集，客户端过滤字段列名称'
                        },
                        {
                            id: '96f30ae6-6fe0-4faa-8b7f-a302a49a0434',
                            name: '过滤列默认值',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            tooltip: '绑定数据集，客户端过滤字段默认值'
                        },
                        {
                            id: 'f3f26cc8-3764-4f0a-8180-a9f88668420c',
                            name: '序列堆积',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            link: 'stack',
                            tooltip: '是否堆积序列，选择Bar后堆积分组需设置相同'
                        },
                        {
                            id: '12343598-8e08-49ce-908e-7524c3032145',
                            name: 'X轴序号',
                            enable: false,
                            type: 'number',
                            value: 0,
                            default: 0,
                            link: 'xAxisIndex',
                            tooltip: 'X轴序号，用于多X轴'
                        },
                        {
                            id: '43213598-8e08-49ce-908e-7524c3087654',
                            name: 'Y轴序号',
                            enable: false,
                            type: 'number',
                            value: 0,
                            default: 0,
                            link: 'yAxisIndex',
                            tooltip: 'Y轴序号，用于多Y轴'
                        },
                        {
                            id: '12343598-8e08-49ce-908e-432135984321',
                            name: '显示标签',
                            enable: false,
                            type: 'checked',
                            value: false,
                            default: false,
                            link: 'label.normal.show',
                            tooltip: '是否显示标签'
                        },
                        {
                            id: '12343598-8e08-49ce-908e-a9f88668420c',
                            name: '标签位置',
                            enable: false,
                            type: 'select',
                            value: 'top',
                            default: 'top',
                            data: [
                                {
                                    value: 'top',
                                    text: 'top'
                                }, {
                                    value: 'left',
                                    text: 'left'
                                }, {
                                    value: 'right',
                                    text: 'right'
                                }, {
                                    value: 'bottom',
                                    text: 'bottom'
                                }, {
                                    value: 'inside',
                                    text: 'inside'
                                }, {
                                    value: 'insideLeft',
                                    text: 'insideLeft'
                                }, {
                                    value: 'insideRight',
                                    text: 'insideRight'
                                }, {
                                    value: 'insideTop',
                                    text: 'insideTop'
                                }, {
                                    value: 'insideBottom',
                                    text: 'insideBottom'
                                }, {
                                    value: 'insideTopLeft',
                                    text: 'insideTopLeft'
                                }, {
                                    value: 'insideBottomLeft',
                                    text: 'insideBottomLeft'
                                }, {
                                    value: 'insideTopRight',
                                    text: 'insideTopRight'
                                }, {
                                    value: 'insideBottomRight',
                                    text: 'insideBottomRight'
                                }
                            ],
                            link: 'label.normal.position',
                            tooltip: '标签所处位置'
                        }, {
                            id: '97876db5-f8e1-49e0-aa57-432135984321',
                            name: '标签字体大小',
                            enable: false,
                            type: 'number',
                            value: 12,
                            default: 12,
                            link: 'label.normal.textStyle.fontSize',
                            tooltip: '标签文字的字体大小'
                        }
                    ],
                    link: 'series',
                    tooltip: '字段说明:<br/>分组控件，支持动态扩展，内部可增加支持的类型属性'
                },
                {
                    group: '事件',
                    id: '6122971c-a8f3-4a02-a497-e4e3e351bb11',
                    name: '序列点击事件',
                    enable: true,
                    type: 'pivotEvent',
                    value: {
                        Event: "SeriesClick",
                        Params: [
                            {Value: "SeriesName", Name: "序列名称"},
                            {Value: "Dimension", Name: "序列维度值"},
                            {Value: "Measure", Name: "序列度量值"}
                        ]
                    },
                    tooltip: '序列点击事件，钻取设置'
                }
            ]).concat($.extend(true, [], Meta.otherProperties)),
        //需要针对组件映射属性至组件Option
        MapOption: function (option) {
            Util.linkOption(this.option, option);

            //link支持function与linkString，下面演示如果没有link时自定义绑定的方法
            //当然，如果上面link已经指定了function，就无需下面的代码了
            // var xAxisSplitLine = _.findWhere(this.option, {name: 'X轴分割线'});
            // var yAxisSplitLine = _.findWhere(this.option, {name: 'Y轴分割线'});
            // if (xAxisSplitLine && xAxisSplitLine.enable && $.isArray(option.xAxis)) {
            //     _.each(option.xAxis, function (xAxis) {
            //         Util.setOption("splitLine.show", xAxisSplitLine.value, xAxis);
            //     });
            // }
            // if (yAxisSplitLine && yAxisSplitLine.enable && $.isArray(option.yAxis)) {
            //     _.each(option.yAxis, function (yAxis) {
            //         Util.setOption("splitLine.show", yAxisSplitLine.value, yAxis);
            //     });
            // }
        }
    };

    var bar = Chart.extend({
        constructor: function (layout) {
            this._layout = layout;
            this._chart = null;
            this._lastdata = null;
            this._container = null;
            this._option = {
                Binding: [],
                Events: [],
                Extend: $.extend(true, {}, property),
                Option: {
                    title: {
                        x: 'center',
                        y: 'top',
                        text: '某地区蒸发量和降水量',
                        subtext: '纯属虚构'
                    },
                    tooltip: {
                        trigger: 'axis'
                    },
                    legend: {
                        x: 'center',
                        y: 'bottom',
                        data: ['蒸发量', '降水量']
                    },
                    toolbox: {
                        show: false
                    },
                    calculable: false,
                    xAxis: [
                        {
                            type: 'category',
                            data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
                        }
                    ],
                    yAxis: [
                        {
                            type: 'value'
                        }
                    ],
                    series: [
                        {
                            name: '蒸发量',
                            type: 'bar',
                            data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
                        },
                        {
                            name: '降水量',
                            type: 'bar',
                            data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
                        }
                    ]
                }
            };
        },
        init: function (element) {
            try {
                this._container = element;
                this._chart = ec.init(element, null, {
                    renderer: 'canvas'
                });
                this._bindEvent();
            } catch (e) {
                log.error(e);
            }
        },
        //TODO:需要重写的部分
        _bindEvent: function () {
            var _this = this;
            this._chart.on("click", function (param) {
                if (_this._layout
                    && _this._layout.navigate
                    && _this._option.Events
                    && _this._option.Events.length > 0) {

                    var registerEvent = _.findWhere(_this._option.Events, {Event: "SeriesClick"});
                    if (registerEvent) {
                        var pageId = registerEvent.PageId;
                        var params = registerEvent.Params;
                        var args = [];
                        var dParam = _.findWhere(params, {Value: "Dimension"});
                        if (dParam && dParam.ParamName) {
                            args.push({
                                ParamName: dParam.ParamName,
                                ParamValue: param.name
                            });
                        }
                        var mParam = _.findWhere(params, {Value: "Measure"});
                        if (mParam && mParam.ParamName) {
                            args.push({
                                ParamName: mParam.ParamName,
                                ParamValue: param.value
                            });
                        }
                        var sParam = _.findWhere(params, {Value: "SeriesName"});
                        if (sParam && sParam.ParamName) {
                            args.push({
                                ParamName: sParam.ParamName,
                                ParamValue: param.seriesName
                            });
                        }
                        _this._layout.navigate(pageId, args);

                    }
                    param.event.event.preventDefault();
                }
            });
            if (!this._filterDataHandle) {
                this._filterDataHandle = function (params) {
                    _this.filterDataHandle.call(_this, params);
                };
            }
            this._layout.removeListener("filterData", this._filterDataHandle);
            this._layout.addListener("filterData", this._filterDataHandle);
        },
        filterDataHandle: function (params) {
            var _this = this;
            var flag = false;
            var seriesItems = _.findWhere(_this._option.Extend.option, {type: 'group'});
            $.each(seriesItems.items, function (i, item) {
                var filterColumn = _.findWhere(item.option, {name: '过滤列名称'});
                var filterValue = _.findWhere(item.option, {name: '过滤列默认值'});

                if (filterColumn && filterValue
                    && filterColumn.enable && filterValue.enable
                    && filterColumn.value !== "" && filterValue.value !== ""
                ) {
                    for (var prop in params) {
                        if (!params.hasOwnProperty(prop)) continue;
                        if (filterColumn.value === prop) {
                            filterValue.value = params[prop];
                            flag = true;
                        }
                    }
                }
            });
            if (flag && _this._lastdata) {
                _this.setData(_this._lastdata);
            }
        },
        example: function () {
            try {
                this._chart.setOption(this._option.Option, true);
            } catch (e) {
                log.error(e);
            }
        },
        _readProperty: function () {
            try {
                if (!this._option.Extend) return;
                Util.deepMapOption(property, this._option.Extend, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        //TODO:需要重写的部分
        _bindData: function (data) {
            var tables = data;
            var _this = this;

            //根据每个option自行查找，可通过id或name，这里因为只有一个group,因此通过type查找
            var seriesItems = _.findWhere(this._option.Extend.option, {type: 'group'});

            if (!$.isArray(this._option.Option.xAxis))
                this._option.Option.xAxis = [this._option.Option.xAxis];

            if (!$.isArray(this._option.Option.yAxis))
                this._option.Option.yAxis = [this._option.Option.yAxis];

            //清除工作
            if (seriesItems.items.length > 0) {
                if (this._option.Option.legend)
                    this._option.Option.legend.data = [];
                $.each(this._option.Option.xAxis, function (i, xAxis) {
                    if (xAxis.type === "category") {
                        xAxis.data = [];
                    } else {
                        delete xAxis.data;
                    }
                });
                $.each(this._option.Option.yAxis, function (i, yAxis) {
                    if (yAxis.type === "category") {
                        yAxis.data = [];
                    } else {
                        delete yAxis.data;
                    }
                });
            }

            var categoryAxis = this._option.Option.yAxis[0].type === "category" ? this._option.Option.yAxis[0] : this._option.Option.xAxis[0];

            //绑定数据
            $.each(seriesItems.items, function (i, item) {
                var bindProperty = _.findWhere(item.option, {type: 'seriesBinding'});
                if (!bindProperty) return;

                var dataSetCode = bindProperty.dataset;
                var dimensionCode = bindProperty.dimension.ColumnCode;
                var measureCode = bindProperty.measure.ColumnCode;

                var nameProperty = _.findWhere(item.option, {name: '序列名称'});
                if (nameProperty) {
                    if (_this._option.Option.legend)
                        _this._option.Option.legend.data.push(nameProperty.value);
                }

                if (dataSetCode && dimensionCode && measureCode) {
                    var table = tables[dataSetCode];

                    var binding = _.findWhere(_this._option.Binding, {DataSetCode: dataSetCode});
                    var dimension = _.findWhere(binding.Dimensions, {Code: dimensionCode}).Column;
                    var measure = _.findWhere(binding.Measures, {Code: measureCode}).Column;
                    var data = [];

                    table = _this._filterTable(item.option, table);
                    $.each(table, function (j, row) {
                        if (categoryAxis.data.indexOf(row[dimension]) === -1) {
                            categoryAxis.data.push(row[dimension]);
                        }
                        //data.push([j, row[measure]]);
                        data.push(row[measure]);
                    });
                    if (_this._option.Option.series.length >= i + 1) {
                        _this._option.Option.series[i].data = data;
                    }
                }
            });
        },
        _filterTable: function (option, table) {
            var filterColumn = _.findWhere(option, {name: '过滤列名称'});
            var filterValue = _.findWhere(option, {name: '过滤列默认值'});

            if (filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                var tableCopy = _.map(table, _.clone);
                return _.filter(tableCopy, function (row) {
                    return row[filterColumn.value] === filterValue.value;
                });
            }
            return table;
        },
        setData: function (data) {
            try {
                this._lastdata = data;
                this._readProperty();

                if (data
                    && this._option.Binding
                    && this._option.Binding.length > 0
                    && this._option.Extend) {

                    this._bindData(data);

                    this._readProperty();
                }

                var _this = this;
                setTimeout(function () {
                    _this._chart.setOption(_this._option.Option, true);
                    //Util.setEChartsMeta(_this, _this._container, _this._option.Extend.option);
                });

            } catch (e) {
                log.error(e);
            }
        },
        setOption: function (option) {
            try {
                return this._option = $.extend(true, {}, option);
            } catch (e) {
                log.error(e);
            }
        },
        getOption: function () {
            try {
                this._readProperty();
            } catch (e) {
                log.error(e);
            }
            return this._option;
        },
        setTheme: function (theme) {
            try {
                this._chart.setTheme(theme);
            } catch (e) {
                log.error(e);
            }
        },
        resize: function () {
            try {
                this._chart.resize();
            } catch (e) {
                log.error(e);
            }
        },
        showLoading: function () {
            try {
                if (this._layout && this._layout.showLoading) {
                    this._layout.showLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        hideLoading: function () {
            try {
                if (this._layout && this._layout.hideLoading) {
                    this._layout.hideLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        dispose: function () {
            try {
                this._chart.dispose();
                this._layout.removeListener("filterData", this._filterDataHandle);
            } catch (e) {
                log.error(e);
            }
        },
        getElement: function () {
            return this._container;
        },
        getChart: function () {
            return this._chart;
        }
    });

    return {
        Chart: bar,
        Property: property
    };
});
